home *** CD-ROM | disk | FTP | other *** search
/ Day Cry / Day Cry CD.bin / oh_towns / taropyon / splib / splib.lzh / PRG / ZMODEM / RBSB.C < prev    next >
C/C++ Source or Header  |  1993-12-16  |  10KB  |  461 lines

  1. /*
  2.  * Rev 5-09-89 This file contains Unix specific code for setting terminal modes,
  3.  * very little is specific to ZMODEM or YMODEM per se (that code is in sz.c
  4.  * and rz.c).  The CRC-16 routines used by XMODEM, YMODEM, and ZMODEM are
  5.  * also in this file, a fast table driven macro version
  6.  *
  7.  * V7/BSD HACKERS:    SEE NOTES UNDER mode(2) !!!
  8.  *
  9.  * This file is #included so the main file can set parameters such as HOWMANY.
  10.  * See the main files (rz.c/sz.c) for compile instructions. */
  11.  
  12. #ifdef V7
  13. #    include <sys/types.h>
  14. #    include <sys/stat.h>
  15. #    define STAT
  16. #    include <sgtty.h>
  17. #    define OS "V7/BSD"
  18. #    define ROPMODE "r"
  19. #    ifdef LLITOUT
  20. long        Locmode;            /* Saved "local mode" for 4.x BSD "new
  21.                                  * driver" */
  22. long        Locbit = LLITOUT;    /* Bit SUPPOSED to disable output
  23.                                  * translations */
  24. #        include <strings.h>
  25. #    endif
  26. #endif
  27.  
  28. #ifdef    __TOWNS__
  29. #    define OS "TownsOS"
  30. #    define ROPMODE "rb"
  31. #    define MODE2OK
  32. #else
  33. #    ifndef OS
  34. #        ifndef USG
  35. #            define USG
  36. #        endif
  37. #    endif
  38.  
  39. #    ifdef USG
  40. #        include <sys/types.h>
  41. #        include <sys/stat.h>
  42. #        define STAT
  43. #        define OS "SYS III/V"
  44. #        define ROPMODE "r"
  45. #        define MODE2OK
  46. #        include <string.h>
  47. #    endif
  48. #endif
  49.  
  50. #ifdef T6K
  51. #    include <sys/ioctl.h>        /* JPRadley: for the Tandy 6000 */
  52. #endif
  53.  
  54. #if HOWMANY  > 255
  55. Howmany must be 255 or less
  56. #endif
  57.  
  58. /*
  59.  * return 1 iff stdout and stderr are different devices indicating this
  60.  * program operating with a modem on a different line
  61.  */
  62. int         Fromcu;             /* Were called from cu or yam */
  63.  
  64. void    from_cu(void)
  65. {
  66. #ifdef    __TOWNS__
  67.     Fromcu = 1;
  68. #else
  69.     struct stat a, b;
  70.  
  71.     fstat(1, &a);
  72.     fstat(2, &b);
  73.     Fromcu = a.st_rdev != b.st_rdev;
  74.     return;
  75. #endif
  76. }
  77.  
  78. void    cucheck(void)
  79. {
  80.     if ( Fromcu )
  81.         USR_fprintf(stderr, "Please read the manual page BUGS chapter!\r\n");
  82. }
  83.  
  84.  
  85. #ifndef    __TOWNS__
  86. struct
  87. {
  88.     unsigned    baudr;
  89.     int         speedcode;
  90. } speeds[] =
  91. {
  92.       110, B110,
  93.       300, B300,
  94.       600, B600,
  95.      1200, B1200,
  96.      2400, B2400,
  97.      4800, B4800,
  98.      9600, B9600,
  99.     19200, EXTA,
  100.     38400, EXTB,
  101.     0,
  102. };
  103. #endif
  104.  
  105. int         Twostop;            /* Use two stop bits */
  106.  
  107. /*
  108.  * The following uses an external rdchk() routine if available, otherwise
  109.  * defines the function for BSD or fakes it for SYSV.
  110.  */
  111.  
  112. #ifdef    __TOWNS__
  113. #    ifdef    READCHECK
  114.     int        rdchk(int f)
  115.     {
  116.         if ( RS_chk(RsPort) > 0 )
  117.             return (1);
  118.         else
  119.             return (0);
  120.     }
  121. #    endif
  122. #endif
  123.  
  124. #ifndef READCHECK
  125. #ifdef FIONREAD
  126. #define READCHECK
  127. /*
  128.  * Return non 0 iff something to read from io descriptor f
  129.  */
  130. rdchk(f)
  131. {
  132.     static long lf;
  133.  
  134.     ioctl(f, FIONREAD, &lf);
  135.     return ((int) lf);
  136. }
  137.  
  138. #else                            /* FIONREAD */
  139.  
  140. #ifdef SV
  141. #define READCHECK
  142. #include <fcntl.h>
  143.  
  144. int         checked = 0;
  145. /*
  146.  * Nonblocking I/O is a bit different in System V, Release 2 Note: this rdchk
  147.  * vsn throws away a byte, OK for ZMODEM sender because protocol design
  148.  * anticipates this problem.
  149.  */
  150. #define EATSIT
  151. rdchk(f)
  152. {
  153.     int         lf, savestat;
  154.     static char bchecked;
  155.  
  156.     savestat = fcntl(f, F_GETFL);
  157.     fcntl(f, F_SETFL, savestat | O_NDELAY);
  158.     lf = read(f, &bchecked, 1);
  159.     fcntl(f, F_SETFL, savestat);
  160.     checked = bchecked & 0377;    /* force unsigned byte */
  161.     return (lf);
  162. }
  163. #endif
  164. #endif
  165. #endif
  166.  
  167.  
  168. static unsigned    getspeed(int code)
  169. {
  170. #ifdef    __TOWNS__
  171.     switch ( code )
  172.     {
  173.         case RSBAUD_300:    return (300);
  174.         case RSBAUD_600:    return (600);
  175.         case RSBAUD_1200:    return (1200);
  176.         case RSBAUD_2400:    return (2400);
  177.         case RSBAUD_4800:    return (4800);
  178.         case RSBAUD_9600:    return (9600);
  179.         case RSBAUD_19200:    return (19200);
  180.         case RSBAUD_38400:    return (38400);
  181.         default:            return (9600);
  182.     }
  183. #else
  184.     register int    n;
  185.  
  186.     for ( n = 0; speeds[n].baudr; ++n )
  187.         if (speeds[n].speedcode == code)
  188.             return speeds[n].baudr;
  189.     return 38400;                /* Assume fifo if ioctl failed */
  190. #endif
  191. }
  192.  
  193.  
  194. #ifdef    __TOWNS__
  195.     static int    OldMd, OldBaud;
  196.     static int    SavePort = -1;
  197. #else
  198. #ifdef ICANON
  199. struct termio oldtty, tty;
  200. #else
  201. struct sgttyb oldtty, tty;
  202. struct tchars oldtch, tch;
  203. #endif
  204. #endif
  205.  
  206. #ifdef    __TOWNS__
  207. static    int        rsOpenChk(int port)
  208. {
  209.     extern    int        RsBaud;
  210.     extern    int        RsMd;
  211.  
  212.     if ( RsCtrl[port].use == 0 )
  213.     {
  214.         RS_open( port );
  215.         if ( RsBaud >= 0 || RsMd >= 0 )
  216.         {
  217.             int        baud;
  218.             int        md;
  219.  
  220.             baud = ( RsBaud >= 0 ) ? RsBaud : RsCtrl[RsPort].rsb->baud;
  221.             md   = ( RsMd >= 0 ) ? RsMd : RsCtrl[RsPort].rsb->mode;
  222.             RS_reopen(RsPort, md, baud );
  223.         }
  224.     }
  225.     return (1); /* OK */
  226. }
  227. #endif
  228.  
  229. /*
  230.  * mode(n)
  231.  *   3: save old tty stat, set raw mode with flow control
  232.  *   2: set XON/XOFF for sb/sz with ZMODEM or YMODEM-g
  233.  *   1: save old tty stat, set raw mode
  234.  *   0: restore original tty mode
  235.  */
  236. static    int        mode(int n)
  237. {
  238.     static int    did0 = FALSE;
  239.  
  240.     vfile("mode:%d", n);
  241.     switch (n)
  242.     {
  243. #ifdef    __TOWNS__
  244.         case 2:            /* set XON/XOFF for sb/sz with ZMODEM or YMODEM-g */
  245.             if (!did0)
  246.             {
  247.                 if ( rsOpenChk( RsPort ) )
  248.                 {
  249.                     OldMd   = RsCtrl[RsPort].rsb->mode;
  250.                     OldBaud = RsCtrl[RsPort].rsb->baud;
  251.                 } else
  252.                     return ERROR;
  253.             }
  254.             {
  255.                 int        md, baud;
  256.                 md   = OldMd | RSMD_XCTRL_ON;
  257.                 RS_reopen(RsPort, md, OldBaud);    /* XCTRL ON */
  258.             }
  259.             RSB_CTRL(RsPort,0x22);
  260.             did0 = TRUE;
  261.             return OK;
  262.  
  263.         case 1:    /* save old tty stat, set raw mode */
  264.         case 3:    /* save old tty stat, set raw mode with flow control */
  265.             if (!did0)
  266.             {    /* save */
  267.                 if ( rsOpenChk( RsPort ) )
  268.                 {
  269.                     OldMd   = RsCtrl[RsPort].rsb->mode;
  270.                     OldBaud = RsCtrl[RsPort].rsb->baud;
  271.                 } else
  272.                     return ERROR;
  273.             }
  274.             {
  275.                 int        md, baud;
  276.  
  277.                 md   = OldMd & (~RSMD_XCTRL_ON);    /* XCTRL OFF */
  278.                 RS_reopen(RsPort, md, OldBaud);
  279.                 RSB_CTRL(RsPort,0x22);
  280.             }
  281.             /*Effbaud =*/ Baudrate = getspeed(OldBaud);
  282.             did0 = TRUE;
  283.             return OK;
  284.  
  285.         case 0: /* restore original tty mode */
  286.             if (!did0)
  287.                 return ERROR;
  288.             RS_reopen(RsPort, OldMd, OldBaud);
  289.             did0 = FALSE;
  290.             return OK;
  291.  
  292.         default:
  293.             return ERROR;
  294. #else
  295. #ifdef USG
  296.         case 2:         /* Un-raw mode used by sz, sb when -g
  297.                                  * detected */
  298.             if (!did0)
  299.                 (void) ioctl(0, TCGETA, &oldtty);
  300.             tty = oldtty;
  301.  
  302.             tty.c_iflag = BRKINT | IXON;
  303.  
  304.             tty.c_oflag = 0;    /* Transparent output */
  305.  
  306.             tty.c_cflag &= ~PARENB;     /* Disable parity */
  307.             tty.c_cflag |= CS8; /* Set character size = 8 */
  308.             if (Twostop)
  309.                 tty.c_cflag |= CSTOPB;    /* Set two stop bits */
  310.  
  311.  
  312. #ifdef READCHECK
  313.             tty.c_lflag = Zmodem ? 0 : ISIG;
  314.             tty.c_cc[VINTR] = Zmodem ? -1 : 030;        /* Interrupt char */
  315. #else
  316.             tty.c_lflag = ISIG;
  317.             tty.c_cc[VINTR] = Zmodem ? 03 : 030;        /* Interrupt char */
  318. #endif
  319.             tty.c_cc[VQUIT] = -1;        /* Quit char */
  320. #ifdef NFGVMIN
  321.             tty.c_cc[VMIN] = 1;
  322. #else
  323.             tty.c_cc[VMIN] = 3; /* This many chars satisfies reads */
  324. #endif
  325.             tty.c_cc[VTIME] = 1;/* or in this many tenths of seconds */
  326.  
  327.             (void) ioctl(0, TCSETAW, &tty);
  328.             did0 = TRUE;
  329.             return OK;
  330.         case 1:
  331.         case 3:
  332.             if (!did0)
  333.                 (void) ioctl(0, TCGETA, &oldtty);
  334.             tty = oldtty;
  335.  
  336.             tty.c_iflag = n == 3 ? (IGNBRK | IXOFF) : IGNBRK;
  337.  
  338.             /* No echo, crlf mapping, INTR, QUIT, delays, no erase/kill */
  339.             tty.c_lflag &= ~(ECHO | ICANON | ISIG);
  340.  
  341.             tty.c_oflag = 0;    /* Transparent output */
  342.  
  343.             tty.c_cflag &= ~PARENB;     /* Same baud rate, disable parity */
  344.             tty.c_cflag |= CS8; /* Set character size = 8 */
  345.             if (Twostop)
  346.                 tty.c_cflag |= CSTOPB;    /* Set two stop bits */
  347. #ifdef NFGVMIN
  348.             tty.c_cc[VMIN] = 1; /* This many chars satisfies reads */
  349. #else
  350.             tty.c_cc[VMIN] = HOWMANY;    /* This many chars satisfies reads */
  351. #endif
  352.             tty.c_cc[VTIME] = 1;/* or in this many tenths of seconds */
  353.             (void) ioctl(0, TCSETAW, &tty);
  354.             did0 = TRUE;
  355.             Effbaud = Baudrate = getspeed(tty.c_cflag & CBAUD);
  356.             return OK;
  357. #endif
  358.  
  359. #ifdef V7
  360.             /*
  361.              * NOTE: this should transmit all 8 bits and at the same time
  362.              * respond to XOFF/XON flow control.  If no FIONREAD or other
  363.              * rdchk() alternative, also must respond to INTRRUPT char This
  364.              * doesn't work with V7.  It should work with LLITOUT, but
  365.              * LLITOUT was broken on the machine I tried it on.
  366.              */
  367.         case 2:         /* Un-raw mode used by sz, sb when -g
  368.                                  * detected */
  369.             if (!did0)
  370.             {
  371.                 ioctl(0,